做完文章的系統,以及自動化測試之後,我們要開始允許用戶撰寫文章了。
在[Day 22] 實作用戶權限!談 Laravel Policy 這篇文章裡面,我們提到了如何用 Laravel Policy 來協助我們管理文章編輯的權限。
其實,Laravel 還提供另一種管理權限的方式,而且比起 Laravel Policy 要更簡單!這個做法就是標題所說的 Laravel Gate
今天我們就來學看看怎麼使用 Laravel Gate
根據官方的說明
Laravel provides two primary ways of authorizing actions: gates and policies. Think of gates and policies like routes and controllers. Gates provide a simple, closure-based approach to authorization while policies, like controllers, group logic around a particular model or resource.
簡單的說,比起功能比較完整的 Laravel Policy,Laravel Gate 可以提供比較容易撰寫,但是功能相對單純的權限管理。
要撰寫 gate
,我們要先定義在 App\Providers\AuthServiceProvider
裡面的 boot()
裡面:
use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Gate::define('update-post', function (User $user, Post $post) {
return $user->id === $post->user_id;
});
}
當然,如果你想沿用已經撰寫好的 Policy,也是可以的
use App\Policies\PostPolicy;
use Illuminate\Support\Facades\Gate;
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Gate::define('update-post', [PostPolicy::class, 'update']);
}
定義好了之後,我們就可以任意地在 controller 內使用這個 gate
if (! Gate::allows('update-post', $post)) {
abort(403);
}
就這樣!是不是很簡單呢?
你也可以宣告一個會回傳特定回應的 gate
use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
Gate::define('edit-settings', function (User $user) {
return $user->isAdmin
? Response::allow()
: Response::deny('You must be an administrator.');
});
這樣就可以客製化自己希望的回傳內容了。
除了客製化內容,你也可以客製化回傳的 HTTP action
use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
Gate::define('edit-settings', function (User $user) {
return $user->isAdmin
? Response::allow()
: Response::denyWithStatus(418);// I am a teapot
});
如果你只是想回傳單純的 404,還可以寫得更加語意化
use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
Gate::define('edit-settings', function (User $user) {
return $user->isAdmin
? Response::allow()
: Response::denyAsNotFound();
});
在某些狀況,你可能會覺得註冊 gate 還是太麻煩了,希望可以有更簡單的用法,Laravel 還可以這樣寫
use Illuminate\Support\Facades\Gate;
Gate::allowIf(fn ($user) => $user->isAdministrator());
這樣一來,如果用戶不是 Administrator
的話,Laravel 就會自動拋出 AuthorizationException
,變成回傳的時候就會自動變成 403 Forbidden 了!是不是很方便呢?
今天有關權限的分享就到這邊。各位明天見!